﻿using System;
using System.Collections.Generic;
using System.ComponentModel.Composition.Hosting;
using System.ComponentModel.Composition;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using ICSharpCode.SharpZipLib.Zip;
using Microsoft.WindowsAzure;
using Microsoft.WindowsAzure.ServiceRuntime;
using Microsoft.WindowsAzure.StorageClient;
using nwrole.lib;
using nwrole.plugin;

namespace nwrole.Supervisor.WorkerRole {
    //public class AzurePluginProvider : IPluginProvider {

    //    private string serviceName;

    //    [System.ComponentModel.Composition.ImportMany]
    //    IEnumerable<IPlugin> Plugins { get; set; }

    //    #region IPluginProvider

    //    public void SetServiceName(string serviceName) {
    //        this.serviceName = serviceName;

    //        Trace.WriteLine("nwrole.Supervisor.WorkerRole.AzurePluginProvider: SetConfigurationSettingPublisher()");

    //        CloudStorageAccount.SetConfigurationSettingPublisher((configName, configSetter) => {
    //            configSetter(RoleEnvironment.GetConfigurationSettingValue(configName));
    //        });
    //    }

    //    public IPlugin[] GetPlugins() {
    //        return Plugins.ToArray();
    //    }

    //    public PropertyList LoadPluginSettings() {
    //        CloudBlobContainer blobContainer = GetBlobContainer("services");

    //        string filename = serviceName + ".zip";

    //        var blob = blobContainer.GetBlobReference(filename);
    //        blob.FetchAttributes();

    //        string settings = blob.Metadata["PluginSettings"];
    //        if (settings == null)
    //            return null;

    //        Trace.WriteLine("PluginSettings:" + settings);
    //        /*MemoryStream pluginSettingStream = new MemoryStream(Encoding.ASCII.GetBytes(settings));
    //        PropertyList plist = new PropertyList(pluginSettingStream);*/


    //        PropertyList plist = PropertyList.LoadData(System.Web.HttpUtility.HtmlDecode(settings));

    //        return plist;
    //    }

    //    public void SavePluginSettings(PropertyList plist) {

    //        CloudBlobContainer blobContainer = GetBlobContainer("services");

    //        string filename = serviceName + ".zip";

    //        var blob = blobContainer.GetBlobReference(filename);
    //        blob.FetchAttributes();

    //        /*MemoryStream settingStream = new MemoryStream();
    //        plist.Save(settingStream);
    //        StreamReader reader = new StreamReader(settingStream);
    //        string text = reader.ReadToEnd();*/
    //        string text = plist.ToXml();

    //        blob.Metadata["PluginSettings"] = System.Web.HttpUtility.HtmlEncode(text);

    //        blob.SetMetadata();
    //    }
        
    //    /*public PropertyList LoadServiceSettings() {
    //        CloudBlobContainer blobContainer = GetBlobContainer("services");

    //        string filename = serviceName + ".zip";

    //        var blob = blobContainer.GetBlobReference(filename);
    //        blob.FetchAttributes();

    //        string settings = blob.Metadata["ServiceSettings"];

    //        MemoryStream pluginSettingStream = new MemoryStream(Encoding.ASCII.GetBytes(settings));
    //        PropertyList plist = new PropertyList(pluginSettingStream);

    //        return plist;

    //    }

    //    public void SaveServiceSettings(PropertyList plist) {
    //        CloudBlobContainer blobContainer = GetBlobContainer("services");

    //        string filename = serviceName + ".zip";

    //        var blob = blobContainer.GetBlobReference(filename);
    //        blob.FetchAttributes();

    //        MemoryStream settingStream = new MemoryStream();
    //        plist.Save(settingStream);
    //        StreamReader reader = new StreamReader(settingStream);
    //        string text = reader.ReadToEnd();

    //        blob.Metadata["ServiceSettings"] = text;

    //        blob.SetMetadata();
    //    }*/

    //    public void RefreshPlugins() {

    //        /*CloudBlobContainer blobContainer = GetBlobContainer("services");

    //        string filename = serviceName + ".zip";
    //        string localFilePath = Path.Combine(Configuration.ServicesDirectory, filename);

    //        //BlobRequestOptions options;

    //        //CloudBlobClient blobClient = GetBlobClient();
    //        //CloudBlobDirectory servicesDir = blobClient.GetBlobDirectoryReference("serviceName");
            
    //        //var blobs = blobContainer.ListBlobs();
    //        //foreach(var blob in blobs) {
    //        //    //blob
    //        //}
    //        var blob = blobContainer.GetBlobReference(filename);
    //        blob.FetchAttributes();
    //        DateTime dateStamp = DateTime.Parse(blob.Metadata["Date"]);

    //        if (File.Exists(localFilePath)) {
    //            DateTime fileDate = File.GetCreationTimeUtc(localFilePath);
    //            if (fileDate <= dateStamp)
    //                return;

    //            File.Delete(localFilePath);
    //        }

    //        blob.DownloadToFile(localFilePath);
    //        File.SetCreationTimeUtc(localFilePath, dateStamp);

    //        FileStream filestream = File.OpenRead(localFilePath);
    //        UnpackZip(filestream, ServicePath);

    //        string pluginSettings = blob.Metadata["PluginSettings"];
    //        string serviceSettings = blob.Metadata["ServiceSettings"];

    //        MemoryStream pluginSettingStream = new MemoryStream(Encoding.ASCII.GetBytes(pluginSettings));
    //        PropertyList plist = new PropertyList(pluginSettingStream);*/


    //        string applicationDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
    //        string servicesDir = Path.Combine(applicationDirectory, "services");
    //        string serviceDir = Path.Combine(servicesDir, serviceName);

    //        Trace.WriteLine("Service:" + serviceName + " dir:" + serviceDir);

    //        var catalog = new AggregateCatalog();
    //        var container = new CompositionContainer(catalog);
    //        var batch = new CompositionBatch();
    //        batch.AddPart(this);
    //        catalog.Catalogs.Add(new AssemblyCatalog(Assembly.GetExecutingAssembly()));
    //        //catalog.Catalogs.Add(new DirectoryCatalog(ServicePath));
    //        catalog.Catalogs.Add(new DirectoryCatalog(serviceDir));
    //        container.Compose(batch);
    //    }

    //    #endregion

    //    private CloudBlobClient GetBlobClient() {
    //        //var storageAccount = CloudStorageAccount.Parse("DefaultEndpointsProtocol=https;AccountName=<YOURACCOUNTNAME>;AccountKey=<YOURACCOUNTKEY>");
    //        var storageAccount = CloudStorageAccount.FromConfigurationSetting("AzureStorage.ConnectionString");
    //        CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();

    //        // For large file copies you need to set up a custom timeout period
    //        // and using parallel settings appears to spread the copy across multiple threads
    //        // if you have big bandwidth you can increase the thread number below
    //        // because Azure accepts blobs broken into blocks in any order of arrival.
    //        blobClient.Timeout = new System.TimeSpan(1, 0, 0);
    //        blobClient.ParallelOperationThreadCount = 2;

    //        return blobClient;
    //    }
    //    private CloudBlobContainer GetBlobContainer(string name) {

    //        CloudBlobClient blobClient = GetBlobClient();
            
    //        // Get and create the container
    //        CloudBlobContainer blobContainer = blobClient.GetContainerReference(name);
    //        blobContainer.CreateIfNotExist();

    //        // Setup the permissions on the container to be private
    //        var permissions = new BlobContainerPermissions();
    //        permissions.PublicAccess = BlobContainerPublicAccessType.Off;
    //        blobContainer.SetPermissions(permissions);

    //        return blobContainer;
    //    }

    //    private void UnpackZip(Stream stream, string destPath) {
            
    //        //string StorageDirectoryPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
    //        //Directory.CreateDirectory(StorageDirectoryPath);

    //        using (ZipInputStream zipStream = new ZipInputStream(stream)) {
    //            ZipEntry entry;
    //            while ((entry = zipStream.GetNextEntry()) != null) {
    //                /*if (!String.IsNullOrEmpty(entry.Name) && entry.Name.Equals(@"solution.plist", StringComparison.OrdinalIgnoreCase)) {
    //                    MemoryStream dataStream = new MemoryStream();
    //                    byte[] buffer = new byte[8192];
    //                    int size = zipStream.Read(buffer, 0, buffer.Length);
    //                    while (size > 0) {
    //                        dataStream.Write(buffer, 0, size);
    //                        size = zipStream.Read(buffer, 0, buffer.Length);
    //                    };
    //                    dataStream.Seek(0, SeekOrigin.Begin);
    //                    PropertyList plist = new PropertyList(dataStream);
    //                    Id = new Guid(plist.StringForKey("id"));
    //                    Name = plist.StringForKey("name");
    //                    Description = plist.StringForKey("description");
    //                    Author = plist.StringForKey("author");
    //                    Created = plist.DateTimeForKey("created");
    //                    Updated = plist.DateTimeForKey("updated");
    //                    foreach (object dict in plist.ArrayForKey("services"))
    //                        Services.Add(new Service((IDictionary)dict));
    //                } else*/ {
    //                             using (FileStream fileStream = File.Create(Path.Combine(destPath, entry.Name))) {
    //                        byte[] buffer = new byte[8192];
    //                        int size;
    //                        while ((size = zipStream.Read(buffer, 0, buffer.Length)) > 0)
    //                            fileStream.Write(buffer, 0, size);
    //                        fileStream.Close();
    //                    }
    //                    //Files.Add(Path.Combine(StorageDirectoryPath, entry.Name));
    //                }
    //            }
    //        }
    //    }

    //    /*private string ServicePath {
    //        get {
    //            return Path.Combine(Configuration.ServicesDirectory, serviceName);
    //        }
    //    }*/
    //}
}
